package com.orange.framework.interceptor;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.orange.common.base.redis.utils.RedisCache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * API安全检查
 *
 * @Author YWF
 * @Date 2025/5/27 15:35
 */
public abstract class AbstractSecurityInterceptor implements HandlerInterceptor {

    protected final static Logger logger = LoggerFactory.getLogger(AbstractSecurityInterceptor.class);

    @Value("${app.developer.cache_key}")
    protected String appInfoCacheKey;

    @Value("${app.rateLimit.enabled}")
    protected boolean rateLimitEnabled;

    @Value("${app.sign_param.enabled}")
    protected boolean signEnabled;

    /**
     * 限流请求时间，单位秒
     * 默认10秒
     */
    protected static final long RATE_LIMIT_TIME_MILLIS = 10;

    /**
     * 单位时间内允许的请求次数
     */
    protected static final int RATE_LIMIT_COUNT = 5;

    protected final static long REQUEST_OUT_TIME = 5 * 60 * 1000;


    @Autowired
    protected RedisCache redisCache;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        /**
         * 限流逻辑
         */
        if (rateLimitEnabled) {
            this.rateLimiter(request);
        }

        /**
         * 1、签名参数校验
         * 2、接口幂等性检查
         * 3、签名校验
         */
        if (signEnabled) {
            this.signParamsCheck(request);
            this.repeatSubmitCheck(request, handler);
            this.verifySign(request);
        }

        return true;
    }

    /**
     * 限流逻辑
     */
    protected abstract void rateLimiter(HttpServletRequest request);

    /**
     * 签名参数校验
     */
    protected abstract void signParamsCheck(HttpServletRequest request);

    /**
     * 接口幂等性检查
     */
    protected abstract void repeatSubmitCheck(HttpServletRequest request, Object handler);

    /**
     * 签名校验
     * @param request
     */
    protected abstract void verifySign(HttpServletRequest request);
}
